﻿using CommonTools;
using Newtonsoft.Json;
using shop.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace shop.Bll.cost
{
    public class PostPriceBll : IPageBll<PostPriceDto>
    {
        public string Title => "物流资费";

        public bool EnableEditOnList => false;

        public bool EnableCreateOnList => false;

        public bool RefreshOnOpen => true;

        public Action<int> TurnPage { set; get; }
        public PostPriceDto CopyItem(PostPriceDto item)
        {
            if (item == null)
                return null;

            var newItem = item.Clone();
            newItem.Id = 0;
            newItem.isdel = false;

            return newItem;
        }

        public PostPriceDto CreateItem()
        {
            return new PostPriceDto() { isdel = false, FUser = UserBll.CurrentUser.Name, FTime = DateTime.Now, };
        }

        public async Task<Result> DeleteItem(int id)
        {
            await DB.FSql.Update<PostPrice>()
                .Where(a => a.Id == id && a.isdel == false)
                .Set(a => a.isdel, true)
                .ExecuteAffrowsAsync();

            await DB.FSql.Insert(new CLogs()
            {
                DocName = nameof(PostPrice),
                Computer = UserBll.CurrentUser.ComputerInfo,
                Zdr = UserBll.CurrentUser.Name,
                DocId = id.ToString(),
                DocAction = "删除",
            })
                .ExecuteAffrowsAsync();

            return new Result(true);
        }


        public async Task<Result<int>> EditCell(string dataPropertyName, object value, PostPriceDto data)
        {
            return await Task.FromResult(new Result<int>());

            //if (data.Id == 0)
            //{
            //    data.FTime = await DB.FSql.GetTimeAsync();
            //    data.FUser = UserBll.CurrentUser.Name;
            //    data.isdel = false;

            //    var nid = await DB.FSql.Insert(data)
            //        .ExecuteIdentityAsync();

            //    data.Id = (int)nid;

            //}

            //var dbRes = await DB.FSql.Update<PostPrice>()
            //    .Where(a => a.Id == data.Id && a.isdel == false)
            //    .SetDto(new Dictionary<string, object> { [dataPropertyName] = value })
            //    .ExecuteAffrowsAsync();

            //return new Result<int>(true, null, data.Id);
        }

        public IEnumerable<DeclareColumn> GetColumns()
        {
            return new[]
           {
                new DeclareColumn(nameof(PostPriceDto.Id),"Id"){ Visible= false},
                new DeclareColumn(nameof(PostPriceDto.BeginDate),"起始日期"){ ValueType= typeof(DateTime), Format="yyyy-MM-dd"},
                new DeclareColumn(nameof(PostPriceDto.EndDate),"截止日期"){ ValueType= typeof(DateTime), Format="yyyy-MM-dd"},
                new DeclareColumn(nameof(PostPriceDto.logistics_name),"物流公司") { Width = 500},
                new DeclareColumn(nameof(PostPriceDto.provinceJson),"省份"){Width=280},
                new DeclareColumn(nameof(PostPriceDto.StockJson),"仓库"){Width=280},
                new DeclareColumn(nameof(PostPriceDto.SpceialRangeDto),"特殊重量区间"){Width=160},
                new DeclareColumn(nameof(PostPriceDto.SpceialRangePriceDto),"特殊邮资"){Width=100},
                new DeclareColumn(nameof(PostPriceDto.firstWeight),"首重(kg)") { ValueType = typeof(decimal) , Width = 90},
                new DeclareColumn(nameof(PostPriceDto.firstWeightPrice),"首费(元)") { ValueType = typeof(decimal) , Width = 90},
                new DeclareColumn(nameof(PostPriceDto.WeightRangeDto),"重量区间"){Width=110},
                new DeclareColumn(nameof(PostPriceDto.UnitWeightDto),"续重") {  Width = 100},
                new DeclareColumn(nameof(PostPriceDto.UnitWeightPriceDto),"续费"){  Width = 100},
                //new DeclareColumn(nameof(PostPriceDto.WeightRangeDto2),"重量区间2"){Width=110},
                //new DeclareColumn(nameof(PostPriceDto.UnitWeightDto2),"续重2") { ValueType = typeof(decimal) , Width = 90},
                //new DeclareColumn(nameof(PostPriceDto.UnitWeightPriceDto2),"续费2"){ ValueType= typeof(decimal), Width = 90},

                //new DeclareColumn(nameof(PostPriceDto.MinAmount),"面单费"){ ValueType= typeof(decimal), Width = 90},
                new DeclareColumn(nameof(PostPriceDto.MinAmount),"最低收费"){ ValueType= typeof(decimal), Width = 90},
                new DeclareColumn(nameof(PostPriceDto.roundMode),"取整方式"){ Width=90},
                //new DeclareColumn(nameof(PostPriceDto.CalcMethod),"计算策略"){ Width=110},
                new DeclareColumn(nameof(PostPriceDto.weightRatio),"抛重比"){ ValueType= typeof(decimal), Width=90},
            };

            //return new[]
            //{
            //    new DeclareColumn(nameof(PostPrice.Id),"Id"){ Visible= false},
            //    new DeclareColumn(nameof(PostPrice.BeginDate),"起始日期"){ ValueType= typeof(DateTime)},
            //    new DeclareColumn(nameof(PostPrice.EndDate),"截止日期"){ ValueType= typeof(DateTime)},
            //    //new DeclareColumn(nameof(PostPrice.shop_name),"店铺"){ValueType= typeof(string) },
            //    new DeclareColumn(nameof(PostPrice.province),"省份"),
            //    //new DeclareColumn(nameof(PostPrice.city),"城市"),
            //    new DeclareColumn(nameof(PostPrice.logistics_name),"物流公司"),
            //    //new DeclareColumn(nameof(PostPrice.maxWeight) ,"最优重量上限"){ValueType=typeof(decimal)},

            //    //new DeclareColumn(nameof(PostPrice.spWeightRange1),"特殊重量区间1"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice1),"特殊区间1邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange2),"特殊重量区间2"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice2),"特殊区间2邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange3),"特殊重量区间3"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice3),"特殊区间3邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange4),"特殊重量区间4"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice4),"特殊区间4邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange5),"特殊重量区间5"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice5),"特殊区间5邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange6),"特殊重量区间6"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice6),"特殊区间6邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange7),"特殊重量区间7"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice7),"特殊区间7邮资"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spWeightRange8),"特殊重量区间8"){ValueType=typeof(decimal)},
            //    //new DeclareColumn(nameof(PostPrice.spPrice8),"特殊区间8邮资"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.firstWeight),"首重"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.firstWeightPrice),"首重资费"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.weightRange1),"重量区间1"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitWeight1),"续重单位1"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitPrice1),"单位资费1"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.weightRange2),"重量区间2"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitWeight2),"续重单位2"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitPrice2),"单位资费2"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.weightRange3),"重量区间3"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitWeight3),"续重单位3"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitPrice3),"单位资费3"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.weightRange4),"重量区间4"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitWeight4),"续重单位4"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.unitPrice4),"单位资费4"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.roundMode),"取整方式"),
            //    new DeclareColumn(nameof(PostPrice.weightRatio),"抛重比"){ValueType=typeof(decimal)},
            //    new DeclareColumn(nameof(PostPrice.PriceByQty),"按件计费单价"){ValueType=typeof(decimal)},

            //    new DeclareColumn(nameof(PostPrice.FUser),"制单人"),
            //};
        }

        public async Task<PostPriceDto> GetItem(int id)
        {
            var list = await DB.FSql.Select<PostPrice>()
                .Where(a => a.isdel == false && a.Id == id)
                .ToOneAsync();

            return ToDto(list);
        }


        public static PostPriceDto ToDto(PostPrice model)
        {
            if (model == null)
                return null;

            var commonRange = string.IsNullOrEmpty(model.CommonRangeJson) 
                ? new List<SpecialRange>() 
                : JsonConvert.DeserializeObject<List<SpecialRange>>(model.CommonRangeJson);

            var specRange = string.IsNullOrEmpty(model.SpecialRangeJson)
                ? new List<SpecialRange>() 
                : JsonConvert.DeserializeObject<List<SpecialRange>>(model.SpecialRangeJson);


            return new PostPriceDto()
            {
                Id = model.Id,
                BeginDate = model.BeginDate,
                EndDate = model.EndDate,
                provinceJson = model.provinceJson,
                StockJson = model.StockJson,
                logistics_name = model.logistics_name,
                city = model.city,
                //CommonRangeDisplay= commonRange.Select(a=> "<= "+a.WeightRange.ToString("#0.####")+ "\r\n")?.DefaultIfEmpty()?.Aggregate((n,c)=> n+c)?.TrimEnd(),
                SpceialRangeDto = specRange?.Select(a => "<= " + a.WeightRange.ToString("#0.####") + "\r\n")?.DefaultIfEmpty()?.Aggregate((n, c) => n + c)?.TrimEnd(),
                SpceialRangeList = specRange,
                CommonRangeList= commonRange,
                SpceialRangePriceDto = specRange?.Select(a => a.Price.ToString("#0.0000") + "\r\n")?.DefaultIfEmpty()?.Aggregate((n, c) => n + c)?.TrimEnd(),
                firstWeight = model.firstWeight,
                firstWeightPrice = model.firstWeightPrice,
                MinAmount= model.MinAmount,
                WeightRangeDto = "0.0 - " + commonRange.Select(a => a.WeightRange.ToString("#0.0###")).DefaultIfEmpty()?.Aggregate((c, n) => c + "\r\n" + n + " - ")?.TrimEnd(' ', '-'),
                UnitWeightDto = commonRange.Select(a => a.UnitWeight.ToString("#0.0###") + "\r\n")?.DefaultIfEmpty()?.Aggregate((n, c) => n + c)?.TrimEnd(),
                UnitWeightPriceDto = commonRange.Select(a => a.Price.ToString("#0.0###") + "\r\n")?.DefaultIfEmpty()?.Aggregate((n, c) => n + c)?.TrimEnd(),
                roundMode = model.roundMode,
                weightRatio = model.weightRatio,
                //CalcMethod= model.CalcMethod,
            };
        }


        #region 查询参数

        public DateTime? _begin;
        public DateTime? _end;
        private string _shop;
        private string _logi;
        private string _prov;
        private string _stock;
        //private string _calc;


        #endregion

        /// <summary> 查询ui </summary>
        public virtual ControlBuilder GetUIBuilder()
        {
            return new ControlBuilder()
                .Add<DateTime?>(ControlEnum.gtDatePicker, "起始日期", c => _begin = c)
                .Add<DateTime?>(ControlEnum.gtDatePicker, "截止日期", c => _end = c)
                //.Add<string>(ControlEnum.guanTextBox, "查找", c => _find = c)
                //.AddGuanTextBox("店铺", c => _shop = c)
                .AddGuanTextBox("省份", c => _prov = c)
                .AddGuanTextBox("物流公司", c => _logi = c)
                //.AddGuanTextBox("计算策略", c => _calc= c)
                .AddQueryButton("查询");
        }


        /// <summary> 查询 </summary>
        public async Task<PageQueryResult<PostPriceDto>> QueryPage(DocFilterParameter queryPara)
        {
            _end = _end.LastTimeOfDay();

            var list = await DB.FSql.Select<PostPrice>()
                .Where(a => a.isdel == false)
                //.WhereIf(_begin != null, a => a.BeginDate >= _begin.Value.Date || a.EndDate >= _begin.Value.Date)
                .WhereIf(_begin != null, a => a.EndDate >= _begin.Value.Date )
                //.WhereIf(_end != null, a => a.BeginDate <= _end.Value.Date && a.EndDate >= _end.Value.Date)
                .WhereIf(_end != null, a => a.BeginDate <= _end.Value.Date)
                .WhereIf(!string.IsNullOrEmpty(_shop), a => a.shop_name.Contains(_shop))
                .WhereIf(!string.IsNullOrEmpty(_logi), a => a.logistics_name.Contains(_logi))
                .WhereIf(!string.IsNullOrEmpty(_stock), a => a.StockJson.Contains(_stock))
                .WhereIf(!string.IsNullOrEmpty(_prov), a => a.provinceJson.Contains(_prov))
                //.WhereIf(!string.IsNullOrEmpty(_calc), a => a.CalcMethod.Contains(_calc))
                .Page(queryPara.PageNo, queryPara.PageSize)
                .OrderByDescending(a => a.BeginDate)
                .OrderByDescending(a => a.Id)
                .Count(out var c)
                .ToListAsync();

            var res = list.Select(a => ToDto(a)).ToList();

            return new PageQueryResult<PostPriceDto>(true, null, res , c);
        }



        public async Task<Result> SaveItem(PostPriceDto item)
        {
            //return await Task.FromResult( new Result(false, "不支持保存"));

            if (item == null)
            {
                return new Result(false, "系统错误");
            }


            string err = string.Empty;
            ////if (string.IsNullOrEmpty(item.shop_name))
            ////{
            ////    err += "店铺名称不能为空!";
            ////}
            //if (string.IsNullOrEmpty(item.provinceJson))
            //{
            //    err += "省份不能为空";
            //}

            if (string.IsNullOrEmpty(item.logistics_name))
            {
                err += "物流公司不能为空";
            }
            if (item.BeginDate == null)
            {
                err += "起始日期不能为空";
            }

            if (string.IsNullOrEmpty(err) == false)
            {
                return new Result(false, err);
            }

            item.isdel = false;
            item.FTime = await DB.FSql.GetTimeAsync();
            item.FUser = UserBll.CurrentUser.Name;

            if (item.Id <= 0)
            {
                var id = await DB.FSql.Insert<PostPrice>(item)
                    .ExecuteIdentityAsync();

                item.Id = (int)id;
            }
            else
            {
                await DB.FSql.Update<PostPrice>()
                    .SetSource(item)
                    .ExecuteAffrowsAsync();
            }

            return new Result(true);

        }


        public async Task<Result> SaveItem(IEnumerable<PostPriceDto> items)
        {
            return await Task.FromResult( new Result(false, "不支持保存"));
            //if (items == null)
            //{
            //    return new Result(false, "系统错误");
            //}


            //var time = await DB.FSql.GetTimeAsync();

            //foreach (var item in items)
            //{
            //    item.isdel = false;
            //    item.FTime = time;
            //    item.FUser = UserBll.CurrentUser.Name;
            //}

            //await DB.FSql.Insert(items).ExecuteAffrowsAsync();

            //return new Result(true);

        }


    }
}
